package dm_pm;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.Scanner;
import java.util.Vector;

/**
 * 
 * We can use this class for confidence interval calculations...
 * 
 * @author Dossay Oryspayev
 *
 */

public class ConfInter_calculator {
	private static DecimalFormat df =  new DecimalFormat("0.000");
	public static void main(String[] args) {
		/*// test example...
		Vector<Double> data = new Vector<Double>();
		data.add(2.0);
		data.add(2.5);
		data.add(2.3);
		data.add(1.7);
		int sigma = 950;
		double[] res = calcConfInter(sigma, data);
		System.out.println("n = "+res[0]+"\n"+
						   "stanDev = " + res[1] +"\n"+
				           "sigma = " + ((double)sigma/10)+"%\n"+
				           "[minRange, maxRange] = ["+res[2]+", "+res[3]+"]");
		*/
		System.out.println("Starting...");
		Vector<Vector<Double>> data = readData(".\\src\\dm_pm\\output2.csv");
		int sigma = 990;
		Vector<Double[]> results = new Vector<Double[]>();
		for(Vector<Double> vD : data) {
			results.add(calcConfInter(sigma, vD));
		}
		writeData(".\\src\\dm_pm\\output2Conf.csv", results);
		
		System.out.println("Finished...");
	}
	
	private static Double[] calcConfInter(int sigma, Vector<Double> observations) {
		int n = observations.size();
		double totalSum = 0.0;
		for(Double d : observations) {
			totalSum += d;
		}
		double sampleMean = (double) totalSum/n;
		double totalSumSquares = 0.0;
		for(Double d : observations) {
			totalSumSquares += Math.pow((double)(d-sampleMean), 2.0);
		}
		double standardDeviation = (double) Math.sqrt((double)(totalSumSquares/(n-1)));
		
		double delta = getDelta(standardDeviation, sigma, n);
		
		Double[] res = new Double[5];
		res[0] = sampleMean;
		res[1] = standardDeviation;
		res[2] = (double) sampleMean-delta;
		res[3] = (double) sampleMean+delta;
		res[4] = (double) delta*100.0/sampleMean;
		return res;
	}
	
	
	private static double getDelta(double standardDev, int sigma, int n) {
		/*
		 * t values were obtained from
		 * http://www.mysmu.edu/faculty/denisleung/t_table.pdf
		 * 
		 */
		
		if(sigma>999 || sigma<800) {
			System.out.println("Sorry we do not have values for this sigma value.");
			System.out.println("Plz update the tables and run again.");
			System.exit(0);
		}
		
		// divide by 10, when obtained...
		int[] sigma_ = {800, 900, 950, 980, 990, 998, 999};
		
		int sigmaIndex = -1;
		for(int i=0; i<sigma_.length; i++) {
			if(sigma_[i]==sigma) {
				sigmaIndex = i;
				break;
			}
		}
		
		if(sigmaIndex == -1) {
			System.out.println("Sorry sigma value was not found again.");
			System.out.println("Plz update the tables and run again.");
			System.exit(0);
		}		
		
		// stores t-values starting from n=3 until n=27
		double t_values[][] = {
				/*3*/ {1.638, 2.353, 3.182, 4.541, 5.841, 10.215, 12.924},
				/*4*/ {1.533, 2.132, 2.776, 3.747, 4.604, 7.173, 8.610},
				/*5*/ {1.476, 2.015, 2.571, 3.365, 4.032, 5.893, 6.869},
				/*6*/ {1.440, 1.943, 2.447, 3.143, 3.707, 5.208, 5.959},
				/*7*/ {1.415, 1.895, 2.365, 2.998, 3.499, 4.785, 5.408},
				/*8*/ {1.397, 1.860, 2.306, 2.896, 3.355, 4.501, 5.041},
				/*9*/ {1.383, 1.833, 2.262, 2.821, 3.250, 4.297, 4.781},
				/*10*/ {1.372, 1.812, 2.228, 2.764, 3.169, 4.144, 4.587},
				/*11*/ {1.363, 1.796, 2.201, 2.718, 3.106, 4.025, 4.437},
				/*12*/ {1.356, 1.782, 2.179, 2.681, 3.055, 3.930, 4.318},
				/*13*/ {1.350, 1.771, 2.160, 2.650, 3.012, 3.852, 4.221},
				/*14*/ {1.345, 1.761, 2.145, 2.624, 2.977, 3.787, 4.140},
				/*15*/ {1.341, 1.753, 2.131, 2.602, 2.947, 3.733, 4.073},
				/*16*/ {1.337, 1.746, 2.120, 2.583, 2.921, 3.686, 4.015},
				/*17*/ {1.333, 1.740, 2.110, 2.567, 2.898, 3.646, 3.965},
				/*18*/ {1.330, 1.734, 2.101, 2.552, 2.878, 3.610, 3.922},
				/*19*/ {1.328, 1.729, 2.093, 2.539, 2.861, 3.579, 3.883},
				/*20*/ {1.325, 1.725, 2.086, 2.528, 2.845, 3.552, 3.849},
				/*21*/ {1.323, 1.721, 2.080, 2.518, 2.831, 3.527, 3.819},
				/*22*/ {1.321, 1.717, 2.074, 2.508, 2.819, 3.505, 3.792},
				/*23*/ {1.319, 1.714, 2.069, 2.500, 2.807, 3.485, 3.768},
				/*24*/ {1.318, 1.711, 2.064, 2.492, 2.797, 3.467, 3.745},
				/*25*/ {1.316, 1.708, 2.060, 2.485, 2.787, 3.450, 3.725},
				/*26*/ {1.315, 1.706, 2.056, 2.479, 2.779, 3.435, 3.707},
				/*27*/ {1.314, 1.703, 2.052, 2.473, 2.771, 3.421, 3.690}
				};
		
		// we do not have for n=2, so we cannot run for n=3.
		if(n > 27 || n < 4) {
			System.out.println("Sorry t value was not found for this n.");
			System.out.println("Plz update the tables and run again.");
			System.exit(0);
		}
		double val1 = (double)t_values[n-3-1][sigmaIndex]/Math.sqrt(n);
		double val2 = standardDev;
		double delta = val1*val2;
		return delta;
	}
	
	private static Vector<Vector<Double>> readData(String fileName) {
		Vector<Vector<Double>> result = new Vector<Vector<Double>>(); 
        File file = new File(fileName);
        Scanner scanner = null;
        
        for(int i=0; i<26; i++) {
        	result.add(new Vector<Double>());
        }
        
        try {
            scanner = new Scanner(file);
            int lineCounter = 0;
            while(scanner.hasNext()) {
                String line = scanner.nextLine();
                Double dVal = Double.valueOf(line);
                result.elementAt(lineCounter%26).add(dVal);
                lineCounter += 1;
            }
            
        }
        catch(FileNotFoundException e) {
            e.printStackTrace();            
        }
        finally {
            if(scanner != null) {
                scanner.close();                
            }                
        }        
        return result;				
	}
	
	public static void writeData(String fileName, Vector<Double[]> data) {
        FileWriter outFile = null;
        PrintWriter out = null;
        
        try {
            outFile = new FileWriter(fileName);
            out = new PrintWriter(outFile);
            
            for(Double[] arr_d : data) {
                String line = "";
                for(int i=0; i<arr_d.length; i++) {
                	if(i==arr_d.length-1) {
                		line += arr_d[i];
                	}
                	else {
                		line += arr_d[i]+",";
                	}
                }
                out.println(line);
            }
        }
        catch(IOException e) {
            e.printStackTrace();
        }
        finally {
            if(out!=null) {
                out.close();
            }            
        }
    }    
	
}


